﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Xml;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using YArchitech.Revit;

namespace YArchitech.Public
{
	internal class PipeShowHelper
	{
        public static int GetIntAboutColor(System.Drawing.Color color)
		{
			return (int)color.B << 16 | (int)((ushort)((int)color.G << 8 | (int)color.R));
		}

        public static System.Drawing.Color getXMLDataColor(string rgb)
		{
            System.Drawing.Color result = default(System.Drawing.Color);
			if (rgb != "默认")
			{
                result = System.Drawing.Color.FromArgb(int.Parse(rgb.Split(new char[]
				{
					' '
				}).ElementAt(1)), int.Parse(rgb.Split(new char[]
				{
					' '
				}).ElementAt(2)), int.Parse(rgb.Split(new char[]
				{
					' '
				}).ElementAt(3)));
			}
			else
			{
                result = System.Drawing.Color.FromArgb(128, 128, 128);
			}
			return result;
		}

        public static Autodesk.Revit.DB.Color getRevirColor(string colorRGB)
		{
            return new Autodesk.Revit.DB.Color((byte)int.Parse(colorRGB.Split(new char[]
			{
				' '
			}).ElementAt(1)), (byte)int.Parse(colorRGB.Split(new char[]
			{
				' '
			}).ElementAt(2)), (byte)int.Parse(colorRGB.Split(new char[]
			{
				' '
			}).ElementAt(3)));
		}

		public static string getNewRGB(byte R)
		{
			string result = "";
			if (R <= 9)
			{
				result = "00" + R.ToString();
			}
			else if (R <= 99 && R >= 10)
			{
				result = "0" + R.ToString();
			}
			if (R >= 100)
			{
				result = R.ToString();
			}
			return result;
		}

		public void ShowPipe(string filePath, Document doc, bool isElectric, double dDiameter)
		{
			try
			{
				XmlDocument xmlDocument = new XmlDocument();
				xmlDocument.Load(filePath);
				XmlNodeList childNodes = xmlDocument.SelectSingleNode("elevationSet").ChildNodes;
				List<ElementId> list = new List<ElementId>();
				foreach (object obj in childNodes)
				{
					XmlNode xmlNode = (XmlNode)obj;
					if (!(xmlNode.Name != "elevation"))
					{
						list.Clear();
						XmlElement xmlElement = (XmlElement)xmlNode;
						double startElevation = double.Parse(xmlElement.GetAttribute("startElevation")) / 304.8;
						double endElevation = double.Parse(xmlElement.GetAttribute("endElevation")) / 304.8;
						string attribute = xmlElement.GetAttribute("color");
						list.AddRange(PipeShowHelper.GetElements(doc, startElevation, endElevation, typeof(Pipe), BuiltInCategory.OST_PipeCurves));
						list.AddRange(PipeShowHelper.GetElements(doc, startElevation, endElevation, typeof(FamilyInstance), BuiltInCategory.OST_PipeAccessory));
						list.AddRange(PipeShowHelper.GetElements(doc, startElevation, endElevation, typeof(FamilyInstance), BuiltInCategory.OST_PipeFitting));
						if (isElectric)
						{
							if (dDiameter != 0.0)
							{
								list.AddRange(PipeShowHelper.GetElements(doc, startElevation, endElevation, typeof(Conduit), BuiltInCategory.OST_Conduit, dDiameter));
								list.AddRange(PipeShowHelper.GetElements(doc, startElevation, endElevation, typeof(FamilyInstance), BuiltInCategory.OST_ConduitFitting, dDiameter));
							}
							else
							{
								list.AddRange(PipeShowHelper.GetElements(doc, startElevation, endElevation, typeof(Conduit), BuiltInCategory.OST_Conduit));
								list.AddRange(PipeShowHelper.GetElements(doc, startElevation, endElevation, typeof(FamilyInstance), BuiltInCategory.OST_ConduitFitting));
							}
						}
						list.AddRange(PipeShowHelper.GetElements(doc, startElevation, endElevation, typeof(CableTray), BuiltInCategory.OST_CableTray));
						list.AddRange(PipeShowHelper.GetElements(doc, startElevation, endElevation, typeof(FamilyInstance), BuiltInCategory.OST_CableTrayFitting));
						doc.ActiveView.SetYJKProjColorOverrideByElement(list, PipeShowHelper.getRevirColor(attribute));
					}
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
			}
		}

		public static List<ElementId> GetElements(Document doc, double startElevation, double endElevation, Type type, BuiltInCategory category)
		{
			List<ElementId> list = new List<ElementId>();
            bool flag = doc.ActiveView.ViewType == (Autodesk.Revit.DB.ViewType)3 || doc.ActiveView.ViewType == (Autodesk.Revit.DB.ViewType)4;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc, doc.ActiveView.Id);
			filteredElementCollector.OfClass(type).OfCategory(category).ToElements();
			foreach (Element element in filteredElementCollector)
			{
				double num;
				if (element is Pipe || element is Conduit || element is CableTray)
				{
					num = PipeShowHelper.GetElevation(element, flag);
				}
				else if (flag)
				{
					num = (element.Location as LocationPoint).Point.Z;
				}
				else
				{
					num = element.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).AsDouble();
				}
				if (double.Parse(startElevation.ToString("0.000")) <= double.Parse(num.ToString("0.000")) && double.Parse(num.ToString("0.000")) < double.Parse(endElevation.ToString("0.000")))
				{
					list.Add(element.Id);
				}
			}
			return list;
		}

		public static List<ElementId> GetElements(Document doc, double startElevation, double endElevation, Type type, BuiltInCategory category, double dDiameter)
		{
			List<ElementId> list = new List<ElementId>();
            bool flag = doc.ActiveView.ViewType == (Autodesk.Revit.DB.ViewType)3 || doc.ActiveView.ViewType == (Autodesk.Revit.DB.ViewType)4;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc, doc.ActiveView.Id);
			filteredElementCollector.OfClass(type).OfCategory(category).ToElements();
			foreach (Element element in filteredElementCollector)
			{
				double num;
				if (element is Pipe || element is Conduit || element is CableTray)
				{
					num = PipeShowHelper.GetElevation(element, flag);
				}
				else if (flag)
				{
					num = (element.Location as LocationPoint).Point.Z;
				}
				else
				{
					num = element.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).AsDouble();
				}
				if (double.Parse(startElevation.ToString("0.000")) <= double.Parse(num.ToString("0.000")) && double.Parse(num.ToString("0.000")) < double.Parse(endElevation.ToString("0.000")))
				{
					if (element is Conduit)
					{
						if (element.GetParameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).AsDouble() * 304.8 > dDiameter)
						{
							list.Add(element.Id);
						}
					}
					else if (element.GetParameter("公称直径") != null && element.GetParameter("公称直径").AsDouble() * 304.8 > dDiameter)
					{
						list.Add(element.Id);
					}
				}
			}
			return list;
		}

		private static double GetElevation(Element elem, bool bView)
		{
			LocationCurve locationCurve = null;
			if (elem is Pipe)
			{
				locationCurve = ((elem as Pipe).Location as LocationCurve);
			}
			if (elem is Conduit)
			{
				locationCurve = ((elem as Conduit).Location as LocationCurve);
			}
			if (elem is CableTray)
			{
				locationCurve = ((elem as CableTray).Location as LocationCurve);
			}
			double result;
			if (bView)
			{
				result = (locationCurve.Curve as Line).GetEndPoint(0).Z;
			}
			else
			{
				result = elem.GetParameter(BuiltInParameter.RBS_OFFSET_PARAM).AsDouble();
			}
			return result;
		}
	}
}
